package com.dylon.baseStudy;

import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class ForkJoinTest {
	
	
	public static void main(String[] args) throws Exception {
		List<Integer> list1 = new ArrayList<>();
		List<Integer> list2 = new ArrayList<>();
		List<Integer> list3 = new ArrayList<>();
		IntStream.rangeClosed(0, 800).forEach(i -> {
			if (i%2==0) {
				list1.add(i);
			}else {
				list2.add(i);
			}
			list3.add(i);
		});
		Instant start = Instant.now();
//		Thread h1 = new Thread(()->{try {
//			forkList(list1);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}});
//		Thread h2 = new Thread(()->{try {
//			forkList(list2);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}});
//		h1.start();
//		h2.start();
		forkRange();

//		ForkJoinPool fork = new ForkJoinPool(10);
//		fork.invoke(new SumTask(list3, 0, list3.size() - 1));
//		fork.shutdown();
//		fork.awaitTermination(30, TimeUnit.MINUTES);
		
		Instant end = Instant.now();
        System.out.println("耗时：" + Duration.between(start, end).toMillis() + "ms");
	}

	public static void forkList(List<Integer> list) throws Exception {
		ForkJoinPool fork = new ForkJoinPool(10);
		fork.execute(()-> list.stream().parallel().forEach(i -> {
			toPrint(i);
		}));
		fork.shutdown();
		fork.awaitTermination(30, TimeUnit.MINUTES);
	}
	
	public static void forkRange() throws Exception {
		List<Integer> list = new ArrayList<>();
		ForkJoinPool fork = new ForkJoinPool(10);
		fork.execute(()-> IntStream.rangeClosed(0, 100).parallel().forEach(i -> {
			list.add(i);
			toPrint(i);
		}));
		fork.shutdown();
		fork.awaitTermination(30, TimeUnit.MINUTES);
		list.sort((i,j)->Integer.compare(i, j));
		System.out.println(list);
	}
	
	public static void toPrint(int i) {
		try {
			Thread.sleep(1000);
			System.out.println(Thread.currentThread().getName()+ " 结果："+ i);
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	
	
	private static class SumTask extends RecursiveTask<Long> {
        private List<Integer> list;
        private int from;
        private int to;

        public SumTask(List<Integer> list, int from, int to) {
            this.list = list;
            this.from = from;
            this.to = to;
        }

        //此方法为ForkJoin的核心方法：对任务进行拆分  拆分的好坏决定了效率的高低
        @Override
        protected Long compute() {

            // 当需要计算的数字个数小于6时，直接采用for loop方式计算结果
            if (to - from <= 10) {
            	try {
					forkList(list);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            } else { // 否则，把任务一分为二，递归拆分(注意此处有递归)到底拆分成多少分 需要根据具体情况而定
                int middle = (from + to) / 2;
                SumTask taskLeft = new SumTask(list.subList(from, middle), from, middle);
                SumTask taskRight = new SumTask(list.subList(middle + 1, to), middle + 1, to);
                taskLeft.fork();
                taskRight.fork();
                taskLeft.join();
                taskRight.join();
            }
            
            return 1L;
        }
    }
}